package com.nexgo.payment.trans.detail;

import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.nexgo.oaf.apiv3.SdkResult;
import com.nexgo.payment.App;
import com.nexgo.payment.R;
import com.nexgo.payment.aop.annotation.RunOnMainThread;
import com.nexgo.payment.constrant.SysConstant;
import com.nexgo.payment.constrant.TransType;
import com.nexgo.payment.databases.DataSource;
import com.nexgo.payment.databases.TransRecord;
import com.nexgo.payment.util.PrintHelper;
import com.nexgo.payment.util.StringUtils;
import com.nexgo.payment.util.TransUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import io.reactivex.subjects.BehaviorSubject;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 交易列表相关操作
 *
 * @author 谭忠扬-YuriTam
 * @time 2017年08月14日
 */
public class TransListPresenter implements TransListContract.Presenter {
    private Logger mLog = LoggerFactory.getLogger(TransListPresenter.class.getSimpleName());

    private TransListContract.View mView;
    private DataSource mRepository;

    private int currentPage = 0;  //当前页数
    private int currentCount = 0; //当前页交易记录数
    private BehaviorSubject<TransRecord> mSubject;
    private Iterator<TransRecord> mTransRecordIterator;
    private TransRecord mCurrTransRecord;
    private boolean mIsFirstTime = true;
    private boolean mIsCustomerCancel;

    public TransListPresenter(@NonNull TransListContract.View view, @NonNull DataSource repository) {
        mView = checkNotNull(view);
        mView.setPresenter(this);
        mRepository = checkNotNull(repository);
    }

    @Override
    public void start() {
        if (mIsFirstTime) {
            getTransList();
            mIsFirstTime = false;
        }
    }

    @Override
    public void pause() {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void refreshTransList() {
        currentCount = 0;
        currentPage = 0;
        postMainThread(() -> mView.showClearList());
        getTransList();
    }

    @Override
    public void getTransList() {
        List<TransRecord> transList = mRepository.queryListTransRecord(SysConstant.MAX_PAGE_SIZE, 0);
        if (transList == null || transList.size() == 0) {
            postMainThread(() -> mView.showEmptyList());
            return;
        }
        currentPage = 1;
        currentCount = transList.size();
        mLog.debug("当前页数：{}，当前页交易记录数：{}", currentPage, currentCount);
        postMainThread(() -> mView.onTransList(transList, false));
    }

    @Override
    public void getMoreTransList() {
        if (currentCount < SysConstant.MAX_PAGE_SIZE) {
            postMainThread(() -> mView.showNotMoreData());
            return;
        }
        List<TransRecord> transList = mRepository.queryListTransRecord(SysConstant.MAX_PAGE_SIZE,
                currentPage * SysConstant.MAX_PAGE_SIZE);
        if (transList == null || transList.size() == 0) {
            postMainThread(() -> mView.showNotMoreData());
            return;
        }
        ++currentPage;
        currentCount = transList.size();
        mLog.debug("当前页数：{}，当前页交易记录数：{}", currentPage, currentCount);
        postMainThread(() -> mView.onTransList(transList, false));
    }

    @Override
    public void getTransRecord(String traceNum) {
        if (TextUtils.isEmpty(traceNum)) {
            postMainThread(() -> mView.showEmptyInput());
            return;
        }
        if (!TextUtils.isDigitsOnly(traceNum)) {
            postMainThread(() -> mView.showErrInput());
            return;
        }
        TransRecord transRecord = mRepository.queryTransRecord(StringUtils.leftPad(traceNum, 6, '0'));
        if (transRecord == null || !transRecord.getIsSuccess()) {
            postMainThread(() -> mView.showEmptyItem());
            return;
        }
        List<TransRecord> transList = new ArrayList<>();
        transList.add(transRecord);
        currentPage = 1;
        currentCount = transList.size();
        mLog.debug("当前页数：{}，当前页交易记录数：{}", currentPage, currentCount);
        postMainThread(() -> mView.onTransList(transList, true));
    }

    @Override
    public void printDetail() {
        mIsCustomerCancel = false;
        //lr 取未被撤销的交易
        List<TransRecord> transRecords = mRepository.getSuccessfulTransRecordsNotVoid();
        if (transRecords.size() > 0) {
            //初始化打印机
            PrintHelper.printerCfgInit();
            //判断打印机是否缺纸
            if (PrintHelper.isPaperLack()) {
                postMainThread(() -> mView.showPrintLackPaper());
                return;
            }
            PrintHelper.formTransDetailHeader();
            mTransRecordIterator = transRecords.iterator();
            mSubject = BehaviorSubject.create();
            mSubject.doOnNext(transRecord -> mCurrTransRecord = transRecord)
                    .doOnSubscribe(transRecord -> printNext(true))
                    .doOnComplete(() -> postMainThread(() -> mView.setPrintingIndicator(false)))
                    .subscribe(transRecord -> startPrint(transRecord),
                            throwable -> postMainThread(() -> mView.showPrintFail(App.sContext.getString(R.string.print_fail))),
                            () -> PrintHelper.cutPaper());
        }
    }

    @Override
    public void cancelPrintDetail() {
        mLog.debug("用户取消打印明细");
        mIsCustomerCancel = true;
    }

    @Override
    public void continuePrintDetail() {
        mSubject.onNext(mCurrTransRecord);
    }

    /**
     * 打印下一笔
     */
    private void printNext(boolean firstTime) {

        while (mTransRecordIterator.hasNext() && !mIsCustomerCancel) {
            TransRecord next = mTransRecordIterator.next();
            //lr add已撤销交易不打明细
            if ((!TransUtils.isNeedPrintDetail(TransType.values()[next.getTransType()])) || (next.getIsVoid())) {
                continue;
            }
            mSubject.onNext(next);
            return;
        }

        //判断打印机是否缺纸，以免打印过程中缺纸无法中断
        if (PrintHelper.isPaperLack()) {
            postMainThread(() -> mView.showPrintLackPaper());
            return;
        }
        if (firstTime) {
            postMainThread(() -> mView.setPrintingIndicator(true));
        }

        mSubject.onComplete();
    }

    /**
     * 开始打印
     *
     * @param transRecord 记录
     */
    private void startPrint(TransRecord transRecord) {
        PrintHelper.formPrintTransDetail(transRecord);
        PrintHelper.startPrint(false, retCode -> {
            switch (retCode) {
                case SdkResult.Success:
                    printNext(false);
                    break;
                case SdkResult.Printer_PaperLack:
                    postMainThread(() -> mView.showPrintLackPaper());
                    break;
                default:
                    postMainThread(() -> mView.showPrintFail(App.sContext.getString(R.string.print_fail)));
                    mSubject.onComplete();
                    break;
            }
        });
    }

    @RunOnMainThread
    private void postMainThread(Runnable runnable) {
        runnable.run();
    }
}
